home *** CD-ROM | disk | FTP | other *** search
- (herald test)
-
- ;;+ FIx for locatives
-
- (define (introduce-cell var)
- (let ((node (variable-binder var))
- (new-var (create-variable (variable-name var))))
- (set (variable-rep new-var) 'assigned)
- (hack-references var new-var)
- (let-nodes ((call (($ primop/make-cell) 1 (^ cont1)))
- (cont1 (() (v new-var))
- (($ primop/set-location) 1
- (^ cont2) ($ primop/cell-value) (* var) (* new-var)))
- (cont2 (#f) ()))
- (insert-call call cont2 node))))
-
- (define (cell-collapsable? var)
- (every? (lambda (ref)
- (or (and (eq? (node-role ref) (call-arg 3))
- (primop-ref? (call-proc (node-parent ref))
- primop/contents-location))
- (and (eq? (node-role ref) (call-arg 4))
- (primop-ref? (call-proc (node-parent ref))
- primop/set-location))))
- (variable-refs var)))
-
- (define (sort-vars vars)
- (iterate loop ((vars vars) (pointer '()) (scratch '()))
- (cond ((null? vars)
- pointer)
- (else
- (loop (cdr vars) (cons (car vars) pointer) scratch)))))
-
- (define-constant (assigned-var? var)
- (eq? (variable-rep var) 'assigned))
-
- (define (stack-cell? var)
- (and (eq? (variable-rep var) 'assigned)
- (not (variable-definition var))))
-
- (define (consed-heap-cell? var)
- (and (eq? (variable-rep var) 'assigned)
- (eq? (variable-definition var) 'consed-heap-cell)))
-
- (define (heap-cell? var)
- (and (eq? (variable-rep var) 'assigned)
- (eq? (variable-definition var) 'heap-cell)))
-
- (define (close-analyze-body node up henv hvia)
- (cond ((and (primop-node? (call-proc node))
- (eq? (primop-value (call-proc node)) primop/Y))
- (let ((cont ((call-arg 1) node)))
- (if (lambda-node? cont)
- (walk (lambda (var)
- (set (variable-definition var) 'consed-heap-cell))
- (lambda-live cont)))
- (really-close-analyze-body
- (cons cont (call-args (lambda-body ((call-arg 2) node))))
- up henv hvia)))
- (else
- (really-close-analyze-body (call-proc+args node)
- up henv hvia))))
-
- (define (close-analyze-label node heapenv heapvia)
- (let* ((assigned? (any? assigned-var? (lambda-live node)))
- (live (filter (lambda (x) (not (heap-cell? x)))
- (lambda-live node)))
- (need-contour? (or (eq? (lambda-env node) 'needs-link) assigned?)))
- (set (lambda-env node) (create-join-point live heapvia need-contour? node))
- (if (fully-recursive? node)
- (walk (lambda (var)
- (set (variable-definition var) 'consed-heap-cell))
- live))
- (close-analyze-body (lambda-body node) heapvia '() heapvia)))
-
- (define (close-analyze-heap cics live up henv hvia)
- (let* ((cic-vars (map lambda-self-var cics))
- (live (set-difference live cic-vars))
- (global? (or (memq? hvia live)
- (any? (lambda (node)
- (eq? (lambda-env node) 'unit-internal-closure))
- cics)))
- (inter (intersection live henv))
- (link (if (or global? inter)
- hvia
- nil))
- (delta (set-difference (delq! hvia live) henv))
- (assigned? (any? assigned-var? inter)))
- (if (or global? (cdr inter) assigned?)
- (create-closure link cic-vars delta nil up)
- (create-closure nil cic-vars live nil up))
- (walk (lambda (var)
- (if (any? (lambda (cic)
- (memq? var (lambda-live (node-parent (node-parent cic)))))
- cics)
- (set (variable-definition var) 'consed-heap-cell)))
- (filter! assigned-var? delta)) ;too tough
- (walk (lambda (cic)
- (cond ((object-lambda? cic)
- (destructure (((#f proc #f . methods)
- (call-args (lambda-body cic))))
- (walk (lambda (method)
- (set (lambda-env method) (lambda-env cic))
- (close-analyze-body (lambda-body method)
- up
- live
- (lambda-self-var cic)))
- (cons proc methods))))
- (else
- (close-analyze-body (lambda-body cic)
- up
- live
- (lambda-self-var cic)))))
- cics)))
-
-
-
- (define (cell-collapse var)
- (cond ((null? (variable-definition var))
- (set (variable-definition var) 'heap-cell))
- (else
- (set (variable-definition var) 'consed-heap-cell))))
-
- (define (compute-label-arg-specs node label join p-ok? stack-ok? stack?)
- (receive (formals actuals) (if (continuation? label)
- (return (lambda-variables label)
- (call-args node))
- (return (cdr (lambda-variables label))
- (cdr (call-args node))))
- (iterate loop ((actuals actuals)
- (formals formals)
- (arg-specs '())
- (env (join-point-env join))
- (env-specs '())
- (eleft '())
- (regs (cond (p-ok?
- (list AN))
- ((and stack? stack-ok?)
- (list *first-stack-register* AN))
- (else
- (list P AN)))))
- (cond ((null? formals)
- (cond ((null? env)
- (iterate loop ((env-specs env-specs)
- (env eleft)
- (regs regs))
- (cond ((null? env)
- (maybe-set-lambda-max regs)
- (return arg-specs env-specs))
- (else
- (let ((reg (cond ((not (consed-heap-cell? (car env)))
- (get-free-register regs
- p-ok?
- '#t '#t
- '#t))
- ((ok-next-register? (car env)
- regs
- label
- stack-ok?
- stack?
- '#t))
- (else
- (get-free-register regs
- p-ok?
- stack-ok?
- stack?
- '#t)))))
- (loop (cons (cons reg (car env)) env-specs)
- (cdr env)
- (cons reg regs)))))))
- ((and (consed-heap-cell? (car env))
- (in-ok-register? (car env) regs stack-ok? stack? '#t))
- => (lambda (reg)
- (loop actuals
- formals
- arg-specs
- (cdr env)
- (cons (cons reg (car env)) env-specs)
- eleft
- (cons reg regs))))
- (else
- (loop actuals
- formals
- arg-specs
- (cdr env)
- env-specs
- (cons (car env) eleft)
- regs))))
- (else
- (let ((reg (cond ((and (reference-node? (car actuals))
- (in-ok-register?
- (reference-variable (car actuals)) regs
- stack-ok?
- stack?
- '#f)))
- ((and (car formals)
- (ok-next-register? (car formals)
- regs label stack? stack-ok? '#f)))
- (else (get-free-register regs p-ok? stack-ok?
- stack? '#f)))))
- (loop (cdr actuals)
- (cdr formals)
- (cons reg arg-specs)
- env
- env-specs
- eleft
- (cons reg regs))))))))
-
-
- (define (generate-make-cell node)
- (let* ((cont ((call-arg 1) node))
- (reg (get-target-register node cont nil nil)))
- (cond ((and (lambda-node? cont)
- (not (consed-heap-cell? (car (lambda-variables cont)))))
- (mark-continuation node (get-stack-slot node)))
- (else
- (free-register node AN)
- (generate-move (machine-num 4) scratch) ; 1 slot
- (generate-move (machine-num header/cell) AN)
- (generate-slink-call slink/make-extend)
- (mark-continuation node AN)))))
-
- (define (generate-set-fixed-accessor node)
- (destructure (((#f type value loc) (call-args node)))
- (let* ((prim (leaf-value type))
- (loc (leaf-value loc))
- (do-it
- (lambda (access)
- (cond ((or (neq? prim primop/cell-value)
- (consed-heap-cell? loc))
- (let ((reg (->register node loc)))
- (emit risc/store 'l
- access
- (reg-offset reg (primop.location-specs prim)))))
- ((stack-cell? loc)
- (cond ((and (not (register-loc loc)) (temp-loc loc))
- => (lambda (temp)
- (emit risc/store 'l access temp)))
- (else
- (bug "Assigned var not on stack or in register ~s" loc))))
- ((register-loc loc)
- (bug "Assigned heap cell in register ~s" loc))
- (else
- (let ((hl (and (assigned-var-in-heap?
- node
- (lambda-self-var *heap-env*)
- loc)
- (lookup node loc (variable-binder loc)))))
- (if hl (emit risc/store 'l access hl))
- (cond ((temp-loc loc)
- => (lambda (loc)
- (emit risc/store 'l access loc))))))))))
-
- (let ((reg (cond ((lambda-node? value)
- (access/make-closure node value))
- (else
- (->register node (leaf-value value))))))
- (lock reg)
- (do-it reg)
- (unlock reg)))))
-
- (define (generate-fixed-accessor node)
- (destructure (((cont type loc) (call-args node)))
- (if (or (leaf-node? cont) (used? (car (lambda-variables cont))))
- (let* ((type (leaf-value type))
- (base (leaf-value loc)))
- (cond ((or (neq? type primop/cell-value)
- (consed-heap-cell? base))
- (let* ((reg (->register node base))
- (target (get-target-register node cont reg nil)))
- (emit risc/load 'l (reg-offset reg (primop.location-specs type))
- target)
- (mark-continuation node target)))
- ((register-loc base)
- (bug "Assigned var not on stack or in register ~s" base))
- ((temp-loc base)
- => (lambda (temp)
- (lock temp)
- (let ((target (get-target-register node cont nil nil)))
- (unlock temp)
- (generate-move temp target)
- (mark-continuation node target))))
- (else
- (let ((hl (lookup node base (variable-binder base))))
- (protect-access hl)
- (let ((target (get-target-register node cont nil nil)))
- (release-access hl)
- (generate-move hl target)
- (mark-continuation node target)))))))))
-
-
- (define (assigned-var-in-heap? node contour value)
- (iterate loop ((env (get-env contour)) (contour contour))
- (let* ((closure (environment-closure env))
- (a-list (closure-env closure))
- (current-offset (environment-cic-offset env)))
- (cond ((assq value a-list) '#t)
- ((neq? closure *unit*)
- (loop (get-env (caadr a-list)) (caadr a-list)))
- (else '#f)))))
-
-